import i18n from '@/i18n'
import store from '@/store'
import { Message } from 'element-ui'

let contract = null
let timer = null

/**
 * 初始化
 */
const init = () => {
  return new Promise((resolve) => {
    timer = setInterval(() => {
      if (typeof tronWeb === 'undefined') {
        console.log('请先安装TronLink钱包插件')
      } else {
        clearInterval(timer)
        resolve(tronWeb)
      }
    }, 1000)
  })
}

/**
 * 初始化合约
 */
const initContract = (name = 'IDO', showFailMessage = false) => {
  console.log('合约类型：', name)

  const contractAddress =
    store.state[name === 'IDO' ? 'contractAddress' : 'usdtAddress']

  return new Promise((resolve, reject) => {
    tronWeb
      .contract()
      .at(contractAddress)
      .then((res) => {
        contract = res
        console.log('钱包连接成功：', res)
        resolve(res)
      })
      .catch((err) => {
        Message.error(err.message || `${i18n.tc('common.钱包连接失败')}`)
        console.log('钱包连接失败：', err)
        reject(err)
      })

    if (!tronWeb.defaultAddress.base58 && showFailMessage) {
      Message.error(i18n.tc(`common.请先解锁钱包插件`))
    }
  })
}

/**
 * 获取用户钱包地址
 */
const getUserAddress = () => {
  return new Promise((resolve) => {
    timer = setInterval(() => {
      if (tronWeb.defaultAddress.base58) {
        clearInterval(timer)
        resolve(tronWeb.defaultAddress.base58)
      } else {
        console.log('请先解锁TronLink钱包插件')
      }
    }, 500)
  })
}

/**
 * 授权
 */
const approve = () => {
  const usdtAddress = store.state.usdtAddress
  const contractAddress = store.state.contractAddress
  const fromAddress = store.state.userAddress

  return new Promise(async (resolve, reject) => {
    // 1. 判断是否需要授权
    const authList = JSON.parse(localStorage.getItem('authList') || '[]')
    const isAuthed = authList.includes(fromAddress)

    if (isAuthed) {
      // 已授权
      console.log('无需授权额度')
      resolve()
    } else {
      // 无授权
      const trigger = await tronWeb.transactionBuilder.triggerSmartContract(
        usdtAddress,
        'approve(address,uint256)',
        {},
        [
          {
            type: 'address',
            value: contractAddress,
          },
          {
            type: 'uint256',
            value: '100000000000',
          },
        ],
        fromAddress
      )

      console.log('授权信息：', trigger)

      if (trigger) {
        // 签名
        const sign = await tronWeb.trx
          .sign(trigger.transaction)
          .catch((err) => {
            console.log('签名失败：', err)
            Message.error(err || `${i18n.tc('common.签名失败')}`)
            reject(err)
          })

        console.log('签名信息：', sign)

        if (sign) {
          // 广播
          const send = await tronWeb.trx
            .sendRawTransaction(sign)
            .catch((err) => {
              console.log('广播失败：', err)
              Message.error(err || `${i18n.tc('common.广播失败')}`)
              reject(err)
            })

          console.log('广播信息：', send)

          // 已授权列表
          authList.push(fromAddress)
          localStorage.setItem('authList', JSON.stringify(authList))

          resolve(send)
        }
      }
    }
  })
}

/**
 * 检查用户是否已注册过
 * @param {string} userAddress 用户地址
 */
const checkIsRegister = (userAddress = '') => {
  return new Promise((resolve, reject) => {
    contract.methods
      .flag(userAddress)
      .call()
      .then((res) => {
        console.log('检查是否已注册成功：', res)
        resolve(res)
      })
      .catch((err) => {
        console.log('检查是否已注册失败：', err)
        reject(err)
      })
  })
}

/**
 * 注册
 * @param {string} inviteAddress 邀请人地址
 */
const register = (inviteAddress = '') => {
  return new Promise((resolve, reject) => {
    contract.methods
      .register(inviteAddress)
      .send()
      .then((res) => {
        console.log('注册成功：', res)
        resolve(res)
      })
      .catch((err) => {
        console.log('注册失败：', err)
        Message.error(err.message || `${i18n.tc('common.领取失败')}`)
        reject(err)
      })
  })
}

/**
 * 释放（领取）
 * @param {number} usdtAmount USDT金额
 * @param {number} tokenAmount 代币金额
 * @param {string} signature 签名
 */
const release = (usdtAmount = 0, tokenAmount = 0, signature = '') => {
  return new Promise((resolve, reject) => {
    contract.methods
      .release(usdtAmount, tokenAmount, signature)
      .send()
      .then((res) => {
        console.log('释放成功：', res)
        resolve(res)
      })
      .catch((err) => {
        console.log('释放失败：', err)
        Message.error(err.message || `${i18n.tc('common.领取失败')}`)
        reject(err)
      })
  })
}

/**
 * 私募（兑换）
 * @param {number} amount 金额
 */
const presale = (amount = 0) => {
  return new Promise((resolve, reject) => {
    contract.methods
      .presale(amount)
      .send()
      .then((res) => {
        console.log('私募成功：', res)
        resolve(res)
      })
      .catch((err) => {
        console.log('私募失败：', err)
        Message.error(err.message || `${i18n.tc('common.兑换失败')}`)
        reject(err)
      })
  })
}

/**
 * 获取Nonce
 */
const getNonce = () => {
  return new Promise((resolve, reject) => {
    contract.methods
      ._nonce(store.state.userAddress)
      .call()
      .then((res) => {
        console.log('获取Nonce成功：', res)
        resolve(res)
      })
      .catch((err) => {
        console.log('获取Nonce失败：', err)
        reject(err)
      })
  })
}

export default {
  init,
  initContract,
  getUserAddress,
  approve,
  checkIsRegister,
  register,
  release,
  presale,
  getNonce,
}
